package cc.rengu.igas.mcps.core.service.trans.scanpay;
/*
 *Create by fuyp on 2020-4-13
 */

import cc.rengu.igas.channel.upqc.facade.request.B2CConsumeRefundRequest;
import cc.rengu.igas.channel.upqc.facade.request.C2BConsumeRefundRequest;
import cc.rengu.igas.channel.upqc.facade.response.B2CConsumeRefundResponse;
import cc.rengu.igas.channel.upqc.facade.response.C2BConsumeRefundResponse;
import cc.rengu.igas.mcps.common.constant.McpsParamConstant;
import cc.rengu.igas.mcps.common.constant.McpsServiceConstant;
import cc.rengu.igas.mcps.common.constant.McpsTreeNodeConstant;
import cc.rengu.igas.mcps.common.constant.McpsTxnNumConstant;
import cc.rengu.igas.mcps.common.enums.RespCodeEnum;
import cc.rengu.igas.mcps.core.service.base.QrRefundService;
import cc.rengu.igas.mcps.facade.base.Header;
import cc.rengu.igas.mcps.facade.bean.OrderInfoBean;
import cc.rengu.igas.mcps.facade.request.PosQrCodeConsumeRefundRequest;
import cc.rengu.igas.mcps.facade.response.PosQrCodeConsumeRefundResponse;
import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.dao.PayOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.PayOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.BizStatusEnum;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.common.enums.OrderStatusEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;

import java.util.ArrayList;
import java.util.List;

public class UpqcPayRefundService extends QrRefundService {
    @Override
    protected Object bizBeforeCust() throws Exception {
        PosQrCodeConsumeRefundRequest posQrCodeConsumeRefundRequest = new PosQrCodeConsumeRefundRequest();
        return posQrCodeConsumeRefundRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        /*银联二维码支付*/
        BizResponse bizResponse = new BizResponse();
        /*请求报文赋值*/
        PosQrCodeConsumeRefundRequest posQrCodeConsumeRefundRequest = (PosQrCodeConsumeRefundRequest) request;
        ConvertUtil.convertOutput(posQrCodeConsumeRefundRequest);
        /*调用支付宝退款接口*/
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(posQrCodeConsumeRefundRequest.getHeader().getInstId(), posQrCodeConsumeRefundRequest.getMchntNo());
        if (null == mchntInfo) {
            rglog.error("查询商户基本信息失败<{}>", posQrCodeConsumeRefundRequest.getMchntNo());
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        /*从内部数中获取原用户订单、商户订单、支付订单到对象中*/
        UserOrderInfo oriUserOrderInfo = (UserOrderInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.ORIG_USER_ORDER_INFO);
        MchntOrderInfo oriMchntOrderInfo = (MchntOrderInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.ORIG_MCHNT_ORDER_INFO);
        PayOrderInfo oriPayOrderInfo = (PayOrderInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.ORIG_PAY_ORDER_INFO);
        /*生成退款用户订单、商户订单*/
        registerOrderInfo(posQrCodeConsumeRefundRequest, oriUserOrderInfo, oriMchntOrderInfo, oriPayOrderInfo);
        UserOrderInfo userOrderInfo = (UserOrderInfo) xmlTreeUtil.getXmlTreeObjectValue(McpsTreeNodeConstant.USER_ORDER_INFO, UserOrderInfo.class);
        MchntOrderInfo mchntOrderInfo = (MchntOrderInfo) xmlTreeUtil.getXmlTreeObjectValue(McpsTreeNodeConstant.MCHNT_ORDER_INFO, MchntOrderInfo.class);
        /*判断交易码 进行退款*/
        if ("P01MC006".equals(oriMchntOrderInfo.getTxnNum())) {
            bizResponse = upqcC2BPayRefundService(posQrCodeConsumeRefundRequest, userOrderInfo, mchntOrderInfo,
                    oriUserOrderInfo, oriMchntOrderInfo, oriPayOrderInfo, mchntInfo);
        } else {
            bizResponse = upqcB2CPayRefundService(posQrCodeConsumeRefundRequest, userOrderInfo, mchntOrderInfo,
                    oriUserOrderInfo, oriMchntOrderInfo, oriPayOrderInfo, mchntInfo);
        }
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        PosQrCodeConsumeRefundResponse posQrCodeConsumeRefundResponse = (PosQrCodeConsumeRefundResponse) bizResponse.getResult();
        posQrCodeConsumeRefundResponse.setRespCode(bizResponse.getRespCode());
        posQrCodeConsumeRefundResponse.setRespDesc(bizResponse.getRespDesc());
        ConvertUtil.convertInput(posQrCodeConsumeRefundResponse);
    }

    private BizResponse upqcC2BPayRefundService(PosQrCodeConsumeRefundRequest posQrCodeConsumeRefundRequest,
                                                UserOrderInfo userOrderInfo, MchntOrderInfo mchntOrderInfo,
                                                UserOrderInfo oriUserOrderInfo, MchntOrderInfo oriMchntOrderInfo,
                                                PayOrderInfo oriPayOrderInfo, MchntInfo mchntInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        BizResponse<PosQrCodeConsumeRefundResponse> bizResponse = new BizResponse<>();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.SYS_SEQ_NUM);
        PayOrderInfo payOrderInfo = new PayOrderInfo();
        /*设置返回报文头*/
        PosQrCodeConsumeRefundResponse posQrCodeConsumeRefundResponse = new PosQrCodeConsumeRefundResponse();
        posQrCodeConsumeRefundResponse.setHeader(posQrCodeConsumeRefundRequest.getHeader());
        BeanUtil.beanCopy(userOrderInfo, payOrderInfo);
        payOrderInfo.setTxnNum(McpsTxnNumConstant.NPOS_QR_CREFUND_TXN_NUM);
        /*设置支付通道标识,通道类型*/
        payOrderInfo.setMsgDstId(oriPayOrderInfo.getMsgDstId());
        payOrderInfo.setDstChannelType(oriPayOrderInfo.getDstChannelType());
        /*设置支付通道序号*/
        String strIndex = xmlTreeUtil.getXmlTreeStringValue("currentDstCallIndex");
        Integer upqcPayCallIndex = new Integer((StringUtil.isEmptyOrNull(strIndex)) ? "0" : strIndex);
        payOrderInfo.setDstCallIndex(upqcPayCallIndex.toString());
        String dstUpqcCallIndex = Integer.toString(upqcPayCallIndex + 1);
        /*对账唯一主键*/
        payOrderInfo.setChannelReconKey(sysSeqNum);
        /*设置当前支付通道调用序号*/
        xmlTreeUtil.setXmlTreeStringValue("currentDstCallIndex", dstUpqcCallIndex);
        /*设置通道交易码*/
        payOrderInfo.setDstTxnNum(McpsTxnNumConstant.UPQC_C2BCONSUME_REFUND);
        payOrderInfo.setMchntNo(posQrCodeConsumeRefundRequest.getMchntNo());
        /*设置银联二维码*/
        payOrderInfo.setPayType("04");
        payOrderInfo.setPayerAcctInfo(oriPayOrderInfo.getPayerAcctInfo());
        payOrderInfo.setPayeeAcctInfo(oriPayOrderInfo.getPayeeAcctInfo());
        /* 设置退款订单状态，交易状态：0 业务状态 01 处理中*/
        payOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        payOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        payOrderInfo.setOrderAmt(posQrCodeConsumeRefundRequest.getTransAmt());
        if (AmountUtil.compare(oriMchntOrderInfo.getOrderAmt(), posQrCodeConsumeRefundRequest.getTransAmt()) == 0) {
            rglog.debug("支付订单表登记实际退款金额<{}>", oriPayOrderInfo.getRealPayAmt());
            payOrderInfo.setOrderAmt(oriPayOrderInfo.getRealPayAmt());
            payOrderInfo.setRealPayAmt(oriPayOrderInfo.getRealPayAmt());
        } else {
            rglog.debug("部分退款支付订单表登记实际退款金额<{}>", oriPayOrderInfo.getRealPayAmt());
            payOrderInfo.setOrderAmt(posQrCodeConsumeRefundRequest.getTransAmt());
            payOrderInfo.setRealPayAmt(posQrCodeConsumeRefundRequest.getTransAmt());
        }
        /*设置原系统流水号*/
        payOrderInfo.setOrigSysSeqNum(oriPayOrderInfo.getSysSeqNum());
        payOrderInfo.setOrigTxnDate(oriPayOrderInfo.getTxnDate());
        /*付款人账户信息*/
        payOrderInfo.setPayerAcctType(oriPayOrderInfo.getPayerAcctType());
        payOrderInfo.setPayerAcctInfo(oriPayOrderInfo.getPayerAcctInfo());
        /*插入支付订单表*/
        PayOrderInfoMapper payOrderInfoMapper = new PayOrderInfoMapperImpl();
        //payOrderInfoMapper.insertPayOrderInfo(payOrderInfo);
        /*测试 ： 205行代码无法正确注册支付订单表  */
        OrderService orderService1 = new OrderServiceImpl();
        if (!orderService1.registerOrderInfo(null, null, payOrderInfo)) {
            rglog.error("订单创建失败");
            throw new BizException(RespCodeEnum.REGISTER_ORDER_ERROR.getRespCode(), RespCodeEnum.REGISTER_ORDER_ERROR.getRespDesc());
        }
        C2BConsumeRefundRequest c2BConsumeRefundRequest = new C2BConsumeRefundRequest();
        cc.rengu.igas.channel.upqc.facade.base.Header header = new cc.rengu.igas.channel.upqc.facade.base.Header();
        BeanUtil.beanCopy(posQrCodeConsumeRefundRequest.getHeader(), header);
        header.setTxnNum(McpsTxnNumConstant.UPQC_C2BCONSUME_REFUND);
        c2BConsumeRefundRequest.setHeader(header);
        /*判断商户是否为非独立清算连锁商户门店*/
        String mchntNoTem = posQrCodeConsumeRefundRequest.getMchntNo();
        if (null != mchntInfo.getIndependentDataFlag()) {
            if ("11".equals(mchntInfo.getMchntType()) && "N".equals(mchntInfo.getIndependentDataFlag())) {
                mchntNoTem = mchntInfo.getChainMchntNo();
            }
        }
        c2BConsumeRefundRequest.setCupsInstCode(mchntInfo.getCupsInstId());
        c2BConsumeRefundRequest.setCupsMchntNo(posQrCodeConsumeRefundRequest.getMchntNo());
        /*退款金额元转分通道处理*/
        if (AmountUtil.compare(oriMchntOrderInfo.getOrderAmt(), posQrCodeConsumeRefundRequest.getTransAmt()) == 0) {
            rglog.debug("通道实际退款金额<{}>", oriPayOrderInfo.getRealPayAmt());
            c2BConsumeRefundRequest.setOrderAmt(oriPayOrderInfo.getRealPayAmt());
        } else {
            rglog.debug("部分退款通道实际退款金额<{}>", oriPayOrderInfo.getRealPayAmt());
            c2BConsumeRefundRequest.setOrderAmt(posQrCodeConsumeRefundRequest.getTransAmt());
        }
        c2BConsumeRefundRequest.setOrderCcy(McpsParamConstant.INNER_DEFAULT_ORDERCCY);
        c2BConsumeRefundRequest.setOrigOrderId(oriPayOrderInfo.getSysSeqNum());
        c2BConsumeRefundRequest.setOrigOrderTime(oriPayOrderInfo.getTxnDate() + oriPayOrderInfo.getTxnTime());
        c2BConsumeRefundRequest.setOrderId(payOrderInfo.getSysSeqNum());
        c2BConsumeRefundRequest.setOrderTime(payOrderInfo.getTxnDate() + payOrderInfo.getTxnTime());
        DubboService dubboService = new DubboServiceImpl();
        cc.rengu.igas.channel.upqc.facade.result.Result<C2BConsumeRefundResponse> c2BConsumeRefundResponseResult = new cc.rengu.igas.channel.upqc.facade.result.Result();
        c2BConsumeRefundResponseResult = (cc.rengu.igas.channel.upqc.facade.result.Result) dubboService.callDubboService(McpsServiceConstant.UPQC_SERVICE, McpsServiceConstant.UPQC_C2BCONSUMEREFUND_METHOM, c2BConsumeRefundRequest);
        C2BConsumeRefundResponse response = c2BConsumeRefundResponseResult.getResult();
        OrderService orderService = new OrderServiceImpl();
        Header tmpHeader = new Header();
        BeanUtil.beanCopy(posQrCodeConsumeRefundRequest.getHeader(), tmpHeader);
        tmpHeader.setTraceNo(sysSeqNum);
        payOrderInfo.setRespCode(response.getRespCode());
        payOrderInfo.setRespDesc(response.getRespDesc());
        if ("00000000".equals(response.getRespCode())) {
            /*退款成功，设置退款订单时间*/
            /*设置退款订单的交易状态*/
            userOrderInfo.setOrderStatus(OrderStatusEnum.FINISH.getStatus());
            userOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            userOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
            /*设置商户订单表*/
            mchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            mchntOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
            /*设置退款支付订单表中的信息*/
            payOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            payOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
            /*存储退款清算日期和清算主键*/
            payOrderInfo.setChannelSeqNum(response.getSettleKey());
            payOrderInfo.setSettleDate(response.getSettleDate());
            List<MchntOrderInfo> mchntOrderInfoList = new ArrayList<MchntOrderInfo>();
            mchntOrderInfoList.add(mchntOrderInfo);
            /*设置原支付交易的业务状态和更新时间*/
            oriUserOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyyMMddHHmmss"));
            oriMchntOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyyMMddHHmmss"));
            oriPayOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyyMMddHHmmss"));
            /*设置原支付交易业务状态*/
            if (AmountUtil.compare(posQrCodeConsumeRefundRequest.getTransAmt(), oriMchntOrderInfo.getOrderAmt()) == 0) {
                /*商户实际退款金额*/
                mchntOrderInfo.setOrderAmt(oriMchntOrderInfo.getOrderAmt());
                /*商户退款实际清算本金*/
                mchntOrderInfo.setRealSettleAmt(oriMchntOrderInfo.getRealSettleAmt());
                /*累计退款金额*/
                oriMchntOrderInfo.setRefundAmt(posQrCodeConsumeRefundRequest.getTransAmt());
                /*商户结算净额*/
                mchntOrderInfo.setMchntSettleAmt(oriMchntOrderInfo.getMchntSettleAmt());
                /*商户应收/退手续费*/
                mchntOrderInfo.setMchntFee(oriMchntOrderInfo.getMchntFee());
                /*商户实收/退手续费*/
                mchntOrderInfo.setRealMchntFee(oriMchntOrderInfo.getRealMchntFee());
                /*商户营销手续*/
                mchntOrderInfo.setMchntDiscountFee(oriMchntOrderInfo.getMchntDiscountFee());
                /*商户累计退款手续费*/
                oriMchntOrderInfo.setRefundFee(oriMchntOrderInfo.getRefundFee());
                oriMchntOrderInfo.setRealRefundFee(oriMchntOrderInfo.getRealRefundFee());
                /*全额退款*/
                oriUserOrderInfo.setBizStatus(BizStatusEnum.REFUND.getStatus());
                oriMchntOrderInfo.setBizStatus(BizStatusEnum.REFUND.getStatus());
                oriPayOrderInfo.setBizStatus(BizStatusEnum.REFUND.getStatus());
            } else {
                /*部分退货，使用营销试算回来的实收手续费，更新部分退货的原商户订单表*/
                /*累计退款金额=原交易商户订单表中累计退款金额+退款金额*/
                oriMchntOrderInfo.setRefundAmt(AmountUtil.addition(oriMchntOrderInfo.getRefundAmt(), posQrCodeConsumeRefundRequest.getTransAmt()));
                /*累计退款手续费*/
                oriMchntOrderInfo.setRefundFee(AmountUtil.addition(oriMchntOrderInfo.getRefundFee(), mchntOrderInfo.getRefundFee()));
                oriMchntOrderInfo.setRealRefundFee(AmountUtil.addition(oriMchntOrderInfo.getRealRefundFee(), mchntOrderInfo.getRealMchntFee()));
                rglog.debug("订单金额<{}>,累计退款金额<{}>", oriMchntOrderInfo.getRealSettleAmt(), oriMchntOrderInfo.getRefundAmt());
                if (AmountUtil.compare(oriMchntOrderInfo.getRefundAmt(), oriMchntOrderInfo.getOrderAmt()) == 0) {
                    /*更新原交易状态全部退货完成*/
                    rglog.debug("更新原交易状态全部退货完成");
                    oriUserOrderInfo.setBizStatus(BizStatusEnum.REFUND.getStatus());
                    oriMchntOrderInfo.setBizStatus(BizStatusEnum.REFUND.getStatus());
                    oriPayOrderInfo.setBizStatus(BizStatusEnum.REFUND.getStatus());
                } else {
                    /*交易状态*/
                    oriUserOrderInfo.setBizStatus(BizStatusEnum.PART_REFUND.getStatus());
                    oriMchntOrderInfo.setBizStatus(BizStatusEnum.PART_REFUND.getStatus());
                    oriPayOrderInfo.setBizStatus(BizStatusEnum.PART_REFUND.getStatus());
                }
            }
            /* 更新原订单状态(在这更新有待商榷)*/
            List<MchntOrderInfo> oriPaymchntOrderInfoList = new ArrayList<>();
            oriPaymchntOrderInfoList.add(oriMchntOrderInfo);

            GlobalTransUtil.setCacheValue(TransCacheConstant.USER_ORDER_INFO, userOrderInfo);
            int iReturnCode = asynnotify.transactionNotice("MchntTransNoticeService", 1, 0, 0);
            if (0 != iReturnCode) {
                rglog.error("提交交易结果异步通知给商户失败!");
            }

            /*更新原退款订单*/
            orderService.updateOrderInfo(userOrderInfo, mchntOrderInfoList, payOrderInfo);
            /*更新原支付订单*/
            orderService.updateOrderInfo(oriUserOrderInfo, oriPaymchntOrderInfoList, oriPayOrderInfo);
            MchntService mchntService = new MchntServiceImpl();
            mchntService.updateMchntTransLimit(mchntOrderInfo);
            /* 设置返回报文*/
            //////posQrCodeConsumeRefundResponse.setTransState("0");
            //////posQrCodeConsumeRefundResponse.setEpayRrn(payOrderInfo.getSysSeqNum());
            OrderInfoBean orderInfo = new OrderInfoBean();
            BeanUtil.beanCopy(payOrderInfo, orderInfo);
            BeanUtil.nullValueCopy(userOrderInfo, orderInfo);
            BeanUtil.nullValueCopy(mchntOrderInfo, orderInfo);
            posQrCodeConsumeRefundResponse.setOrderInfo(orderInfo);
            bizResponse.setResult(posQrCodeConsumeRefundResponse);
            bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
            bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
            bizResponse.setRspSysId(AppParamConstant.SYS_ID);
            return bizResponse;
        } else if (OltpRpcdEnum.BIZ_PROCESS_TIMEOUT.getRespCode().equals(response.getRespCode())) {
            /*退款超时，默认处理中*/
            //////posQrCodeConsumeRefundResponse.setTransState("9");
            //////posQrCodeConsumeRefundResponse.setEpayRrn(payOrderInfo.getSysSeqNum());
            bizResponse.setResult(posQrCodeConsumeRefundResponse);
            bizResponse.setRespCode(RespCodeEnum.TRANS_PROCESSING.getRespCode());
            bizResponse.setRespDesc(response.getRespDesc());
            bizResponse.setRspSysId(AppParamConstant.SYS_ID);
            return bizResponse;
        } else {
            /*退款失败*/
            /*退款失败，设置退款订单的updatetime*/
            userOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            mchntOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            payOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            /*设置退款订单的交易状态*/
            userOrderInfo.setOrderStatus(OrderStatusEnum.FINISH.getStatus());
            userOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            userOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            /*设置商户订单表*/
            mchntOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            mchntOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            /*设置退款支付订单表中的信息*/
            payOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            payOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            List<MchntOrderInfo> mchntOrderInfoList = new ArrayList<>();
            mchntOrderInfoList.add(mchntOrderInfo);
            /*更新订单相关的信息表*/
            orderService.updateOrderInfo(userOrderInfo, mchntOrderInfoList, payOrderInfo);
            ////posQrCodeConsumeRefundResponse.setTransState("1");
            ////posQrCodeConsumeRefundResponse.setEpayRrn(payOrderInfo.getSysSeqNum());
            bizResponse.setResult(posQrCodeConsumeRefundResponse);
            bizResponse.setRespCode(RespCodeEnum.TRANS_FAILED.getRespCode());
            bizResponse.setRespDesc(response.getRespDesc());
            bizResponse.setRspSysId(AppParamConstant.SYS_ID);
            return bizResponse;
        }
    }

    private BizResponse upqcB2CPayRefundService(PosQrCodeConsumeRefundRequest posQrCodeConsumeRefundRequest,
                                                UserOrderInfo userOrderInfo, MchntOrderInfo mchntOrderInfo,
                                                UserOrderInfo oriUserOrderInfo, MchntOrderInfo oriMchntOrderInfo,
                                                PayOrderInfo oriPayOrderInfo, MchntInfo mchntInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        BizResponse<PosQrCodeConsumeRefundResponse> bizResponse = new BizResponse<>();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.SYS_SEQ_NUM);
        PayOrderInfo payOrderInfo = new PayOrderInfo();
        /*设置返回报文头*/
        PosQrCodeConsumeRefundResponse posQrCodeConsumeRefundResponse = new PosQrCodeConsumeRefundResponse();
        posQrCodeConsumeRefundResponse.setHeader(posQrCodeConsumeRefundRequest.getHeader());
        BeanUtil.beanCopy(userOrderInfo, payOrderInfo);
        payOrderInfo.setTxnNum(McpsTxnNumConstant.NPOS_QR_CREFUND_TXN_NUM);
        /*设置支付通道标识,通道类型*/
        payOrderInfo.setMsgDstId(oriPayOrderInfo.getMsgDstId());
        payOrderInfo.setDstChannelType(oriPayOrderInfo.getDstChannelType());
        /*设置支付通道序号*/
        String strIndex = xmlTreeUtil.getXmlTreeStringValue("currentDstCallIndex");
        Integer upqcPayCallIndex = new Integer((StringUtil.isEmptyOrNull(strIndex)) ? "0" : strIndex);
        payOrderInfo.setDstCallIndex(upqcPayCallIndex.toString());
        String dstUpqcCallIndex = Integer.toString(upqcPayCallIndex + 1);
        /*对账唯一主键*/
        payOrderInfo.setChannelReconKey(sysSeqNum);
        /*设置当前支付通道调用序号*/
        xmlTreeUtil.setXmlTreeStringValue("currentDstCallIndex", dstUpqcCallIndex);
        /*设置通道交易码*/
        payOrderInfo.setDstTxnNum(McpsTxnNumConstant.UPQC_B2CCONSUME_REFUND);
        payOrderInfo.setMchntNo(posQrCodeConsumeRefundRequest.getMchntNo());
        /*设置银联二维码*/
        payOrderInfo.setPayType(oriPayOrderInfo.getPayType());
        /* 设置退款订单状态，交易状态：0 业务状态 01 处理中*/
        payOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        payOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        payOrderInfo.setOrderAmt(posQrCodeConsumeRefundRequest.getTransAmt());
        if (AmountUtil.compare(oriMchntOrderInfo.getOrderAmt(), posQrCodeConsumeRefundRequest.getTransAmt()) == 0) {
            rglog.debug("支付订单表登记实际退款金额<{}>", oriPayOrderInfo.getRealPayAmt());
            payOrderInfo.setRealPayAmt(oriPayOrderInfo.getRealPayAmt());
        } else {
            if (StringUtil.isEmptyOrNull(oriPayOrderInfo.getChannelDiscountAmt()) ||
                    AmountUtil.compare(oriPayOrderInfo.getChannelDiscountAmt(), "0.00") == 0) {
                rglog.debug("原支付时银联没有优惠，部分退款支付订单表登记实际退款金额<{}>", posQrCodeConsumeRefundRequest.getTransAmt());
                payOrderInfo.setRealPayAmt(posQrCodeConsumeRefundRequest.getTransAmt());
            } else {
                String totalRefundAmt = AmountUtil.addition(oriMchntOrderInfo.getRefundAmt(), posQrCodeConsumeRefundRequest.getTransAmt());
                if (AmountUtil.compare(totalRefundAmt, oriMchntOrderInfo.getOrderAmt()) == 0) {
                    String readyFefundRate = AmountUtil.division(oriMchntOrderInfo.getRefundAmt(), oriMchntOrderInfo.getOrderAmt(), 2);
                    String readyRefundAmt = AmountUtil.multiplication(oriMchntOrderInfo.getRefundAmt(), readyFefundRate, 2);
                    payOrderInfo.setRealPayAmt(AmountUtil.subtraction(oriPayOrderInfo.getRealPayAmt(), readyRefundAmt));
                    rglog.debug("原支付订单有银联优惠，最后一次部分退款，支付订单表中登记的实际支付金额<{}>", payOrderInfo.getRealPayAmt());
                } else {
                    String refundRate = AmountUtil.division(posQrCodeConsumeRefundRequest.getTransAmt(), oriMchntOrderInfo.getOrderAmt(), 2);
                    payOrderInfo.setRealPayAmt(AmountUtil.multiplication(oriPayOrderInfo.getRealPayAmt(), refundRate, 2));
                    rglog.debug("原支付订单有银联优惠，部分退款，支付订单表中登记的实际支付金额<{}>", payOrderInfo.getRealPayAmt());
                }
            }
        }
        /*设置原系统流水号*/
        payOrderInfo.setOrigSysSeqNum(oriPayOrderInfo.getSysSeqNum());
        payOrderInfo.setOrigTxnDate(oriPayOrderInfo.getTxnDate());
        /*付款人账户信息*/
        payOrderInfo.setPayerAcctType(oriPayOrderInfo.getPayerAcctType());
        payOrderInfo.setPayerAcctInfo(oriPayOrderInfo.getPayerAcctInfo());
        /*插入支付订单表*/
        OrderService orderService = new OrderServiceImpl();
        if (!orderService.registerOrderInfo(null, null, payOrderInfo)) {
            updateFailOrderInfo("登记支付订单信息失败", userOrderInfo, mchntOrderInfo);
            rglog.error("登记支付订单信息失败,instId:<{}>,sysSeqNum:<{}>,mchntOrderId:<{}>,msgDstId:<{}>",
                    payOrderInfo.getInstId(), payOrderInfo.getSysSeqNum(), payOrderInfo.getMchntOrderId(), payOrderInfo.getMsgDstId());
            throw new BizException(RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespCode(), RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespDesc());
        }
        B2CConsumeRefundRequest b2CConsumeRefundRequest = new B2CConsumeRefundRequest();
        cc.rengu.igas.channel.upqc.facade.base.Header header = new cc.rengu.igas.channel.upqc.facade.base.Header();
        BeanUtil.beanCopy(posQrCodeConsumeRefundRequest.getHeader(), header);
        header.setTxnNum(McpsTxnNumConstant.UPQC_B2CCONSUME_REFUND);
        b2CConsumeRefundRequest.setHeader(header);
        b2CConsumeRefundRequest.setCupsInstCode(mchntInfo.getCupsInstId());
        b2CConsumeRefundRequest.setCupsMchntNo(posQrCodeConsumeRefundRequest.getMchntNo());
        if (AmountUtil.compare(oriMchntOrderInfo.getOrderAmt(), posQrCodeConsumeRefundRequest.getTransAmt()) == 0) {
            rglog.debug("通道实际退款金额<{}>", oriPayOrderInfo.getRealPayAmt());
            b2CConsumeRefundRequest.setOrderAmt(oriPayOrderInfo.getRealPayAmt());
        } else {
            rglog.debug("部分退款通道实际退款金额<{}>", oriPayOrderInfo.getRealPayAmt());
            b2CConsumeRefundRequest.setOrderAmt(posQrCodeConsumeRefundRequest.getTransAmt());
        }
        b2CConsumeRefundRequest.setOrderCcy(McpsParamConstant.INNER_DEFAULT_ORDERCCY);
        b2CConsumeRefundRequest.setOrigOrderId(oriPayOrderInfo.getSysSeqNum());
        b2CConsumeRefundRequest.setOrigOrderTime(oriPayOrderInfo.getTxnDate() + oriPayOrderInfo.getTxnTime());
        b2CConsumeRefundRequest.setOrderId(payOrderInfo.getSysSeqNum());
        b2CConsumeRefundRequest.setOrderTime(payOrderInfo.getTxnDate() + payOrderInfo.getTxnTime());
        rglog.debug("银联退款请求报文{}", JSON.toJSONString(b2CConsumeRefundRequest));
        DubboService dubboService = new DubboServiceImpl();
        cc.rengu.igas.channel.upqc.facade.result.Result<B2CConsumeRefundResponse> b2CConsumeRefundResponseResult = new cc.rengu.igas.channel.upqc.facade.result.Result();
        b2CConsumeRefundResponseResult = (cc.rengu.igas.channel.upqc.facade.result.Result) dubboService.callDubboService(McpsServiceConstant.UPQC_SERVICE, McpsServiceConstant.UPQC_B2CCONSUMEREFUND_METHOM, b2CConsumeRefundRequest);
        B2CConsumeRefundResponse response = b2CConsumeRefundResponseResult.getResult();
        Header tmpHeader = new Header();
        BeanUtil.beanCopy(posQrCodeConsumeRefundRequest.getHeader(), tmpHeader);
        tmpHeader.setTraceNo(sysSeqNum);
        payOrderInfo.setRespCode(response.getRespCode());
        payOrderInfo.setRespDesc(response.getRespDesc());
        if ("00000000".equals(response.getRespCode())) {
            /*退款成功，设置退款订单时间*/
            /*设置退款订单的交易状态*/
            userOrderInfo.setOrderStatus(OrderStatusEnum.FINISH.getStatus());
            userOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            userOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
            userOrderInfo.setRealPayAmt(payOrderInfo.getRealPayAmt());
            /*设置商户订单表*/
            mchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            mchntOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
            /*设置退款支付订单表中的信息*/
            payOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            payOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
            payOrderInfo.setChannelSeqNum(response.getSettleKey());
            payOrderInfo.setSettleDate(response.getSettleDate());
            List<MchntOrderInfo> mchntOrderInfoList = new ArrayList<MchntOrderInfo>();
            mchntOrderInfoList.add(mchntOrderInfo);
            /*设置原支付交易的业务状态和更新时间*/
            oriUserOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyyMMddHHmmss"));
            oriMchntOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyyMMddHHmmss"));
            oriPayOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyyMMddHHmmss"));

            /*设置原支付交易业务状态*/
            if (AmountUtil.compare(posQrCodeConsumeRefundRequest.getTransAmt(), oriMchntOrderInfo.getOrderAmt()) == 0) {
                /*商户实际退款金额*/
                mchntOrderInfo.setOrderAmt(oriMchntOrderInfo.getOrderAmt());
                /*商户退款实际清算本金*/
                mchntOrderInfo.setRealSettleAmt(oriMchntOrderInfo.getRealSettleAmt());
                /*累计退款金额*/
                oriMchntOrderInfo.setRefundAmt(posQrCodeConsumeRefundRequest.getTransAmt());
                /*商户结算净额*/
                mchntOrderInfo.setMchntSettleAmt(oriMchntOrderInfo.getMchntSettleAmt());
                /*商户应收/退手续费*/
                mchntOrderInfo.setMchntFee(oriMchntOrderInfo.getMchntFee());
                /*商户实收/退手续费*/
                mchntOrderInfo.setRealMchntFee(oriMchntOrderInfo.getRealMchntFee());
                /*商户营销手续*/
                mchntOrderInfo.setMchntDiscountFee(oriMchntOrderInfo.getMchntDiscountFee());
                /*商户累计退款手续费*/
                oriMchntOrderInfo.setRefundFee(oriMchntOrderInfo.getRealMchntFee());
                /*全额退款*/
                oriUserOrderInfo.setBizStatus(BizStatusEnum.REFUND.getStatus());
                oriMchntOrderInfo.setBizStatus(BizStatusEnum.REFUND.getStatus());
                oriPayOrderInfo.setBizStatus(BizStatusEnum.REFUND.getStatus());
            } else {
                /*部分退货，使用营销试算回来的实收手续费，更新部分退货的原商户订单表*/
                /*累计退款金额=原交易商户订单表中累计退款金额+退款金额*/
                oriMchntOrderInfo.setRefundAmt(AmountUtil.addition(oriMchntOrderInfo.getRefundAmt(), posQrCodeConsumeRefundRequest.getTransAmt()));
                /*累计退款手续费*/
                oriMchntOrderInfo.setRefundFee(AmountUtil.addition(oriMchntOrderInfo.getRefundFee(), mchntOrderInfo.getRealMchntFee()));
                rglog.debug("订单金额<{}>,累计退款金额<{}>", oriMchntOrderInfo.getRealSettleAmt(), oriMchntOrderInfo.getRefundAmt());
                if (AmountUtil.compare(oriMchntOrderInfo.getRefundAmt(), oriMchntOrderInfo.getOrderAmt()) == 0) {
                    /*更新原交易状态全部退货完成*/
                    rglog.debug("更新原交易状态全部退货完成");
                    oriUserOrderInfo.setBizStatus(BizStatusEnum.REFUND.getStatus());
                    oriMchntOrderInfo.setBizStatus(BizStatusEnum.REFUND.getStatus());
                    oriPayOrderInfo.setBizStatus(BizStatusEnum.REFUND.getStatus());
                } else {
                    /*交易状态*/
                    oriUserOrderInfo.setBizStatus(BizStatusEnum.PART_REFUND.getStatus());
                    oriMchntOrderInfo.setBizStatus(BizStatusEnum.PART_REFUND.getStatus());
                    oriPayOrderInfo.setBizStatus(BizStatusEnum.PART_REFUND.getStatus());
                }
            }
            /* 更新原订单状态(在这更新有待商榷)*/
            List<MchntOrderInfo> oriPaymchntOrderInfoList = new ArrayList<>();
            oriPaymchntOrderInfoList.add(oriMchntOrderInfo);
            /*更新退款订单*/
            if (!orderService.updateOrderInfo(userOrderInfo, mchntOrderInfoList, payOrderInfo)) {
                rglog.error("退款成功，更新用户订单、商户订单、支付订单失败{}", payOrderInfo.getSysSeqNum());
            }
            /*更新原支付订单*/
            rglog.debug("原商户订单表信息更新<{}>", JSON.toJSONString(oriMchntOrderInfo));
            if (!orderService.updateOrderInfo(oriUserOrderInfo, oriPaymchntOrderInfoList, oriPayOrderInfo)) {
                rglog.error("退款成功，更新原用户订单、原商户订单、原支付订单失败{}", oriPayOrderInfo.getSysSeqNum());
            }

            /*调用微信推送,特殊费率商户处理*/
            GlobalTransUtil.setCacheValue(TransCacheConstant.USER_ORDER_INFO, userOrderInfo);
            int iReturnCode = asynnotify.transactionNotice("MchntTransNoticeService", 1, 0, 0);
            if (0 != iReturnCode) {
                rglog.error("提交交易结果异步通知给商户失败!");
            }

            MchntService mchntService = new MchntServiceImpl();
            mchntService.updateMchntTransLimit(mchntOrderInfo);
            /* 设置返回报文*/
            OrderInfoBean orderInfo = new OrderInfoBean();
            BeanUtil.beanCopy(payOrderInfo, orderInfo);
            BeanUtil.nullValueCopy(userOrderInfo, orderInfo);
            posQrCodeConsumeRefundResponse.setOrderInfo(orderInfo);
            bizResponse.setResult(posQrCodeConsumeRefundResponse);
            bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
            bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
            bizResponse.setRspSysId(AppParamConstant.SYS_ID);
            return bizResponse;
        } else if (OltpRpcdEnum.BIZ_PROCESS_TIMEOUT.getRespCode().equals(response.getRespCode())) {
            /*退款超时，默认处理中*/
            OrderInfoBean orderInfo = new OrderInfoBean();
            BeanUtil.beanCopy(payOrderInfo, orderInfo);
            BeanUtil.nullValueCopy(userOrderInfo, orderInfo);
            posQrCodeConsumeRefundResponse.setOrderInfo(orderInfo);
            bizResponse.setResult(posQrCodeConsumeRefundResponse);
            bizResponse.setRespCode(RespCodeEnum.TRANS_PROCESSING.getRespCode());
            bizResponse.setRespDesc(response.getRespDesc());
            bizResponse.setRspSysId(AppParamConstant.SYS_ID);
            return bizResponse;
        } else {
            /*退款失败*/
            /*退款失败，设置退款订单的updatetime*/
            userOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            mchntOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            payOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            /*设置退款订单的交易状态*/
            userOrderInfo.setOrderStatus(OrderStatusEnum.FINISH.getStatus());
            userOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            userOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            /*设置商户订单表*/
            mchntOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            mchntOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            /*设置退款支付订单表中的信息*/
            payOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            payOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            List<MchntOrderInfo> mchntOrderInfoList = new ArrayList<>();
            mchntOrderInfoList.add(mchntOrderInfo);
            /*更新订单相关的信息表*/
            orderService.updateOrderInfo(userOrderInfo, mchntOrderInfoList, payOrderInfo);
            OrderInfoBean orderInfo = new OrderInfoBean();
            BeanUtil.beanCopy(payOrderInfo, orderInfo);
            BeanUtil.nullValueCopy(userOrderInfo, orderInfo);
            posQrCodeConsumeRefundResponse.setOrderInfo(orderInfo);
            bizResponse.setResult(posQrCodeConsumeRefundResponse);
            bizResponse.setRespCode(RespCodeEnum.TRANS_FAILED.getRespCode());
            bizResponse.setRespDesc(response.getRespDesc());
            bizResponse.setRspSysId(AppParamConstant.SYS_ID);
            return bizResponse;
        }
    }

    /**
     * 登记支付订单表，存储用户订单、商户订单、商户结算信息于内部树中
     *
     * @param posQrCodeConsumeRefundRequest 扫码请求信息
     * @throws Exception 异常
     */
    private void registerOrderInfo(PosQrCodeConsumeRefundRequest posQrCodeConsumeRefundRequest,
                                   UserOrderInfo oriUserOrderInfo, MchntOrderInfo oriMchntOrderInfo, PayOrderInfo oriPayOrderInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.SYS_SEQ_NUM);
        MchntService mchntService = new MchntServiceImpl();
        UserOrderInfo userOrderInfo = new UserOrderInfo();
        MchntOrderInfo mchntOrderInfo = new MchntOrderInfo();
        OrderService orderService = new OrderServiceImpl();
        /* 用户订单号和商户订单号 */
        /*初始化用户订单信息*/
        userOrderInfo.setInstId(posQrCodeConsumeRefundRequest.getHeader().getInstId());
        userOrderInfo.setTxnNum(posQrCodeConsumeRefundRequest.getHeader().getTxnNum());
        userOrderInfo.setBizType(posQrCodeConsumeRefundRequest.getHeader().getBizType());
        userOrderInfo.setMsgSrcId(posQrCodeConsumeRefundRequest.getHeader().getSrcSysId());
        userOrderInfo.setTransChannelId(posQrCodeConsumeRefundRequest.getHeader().getChanlId());
        /*系统流水号*/
        userOrderInfo.setSysSeqNum(sysSeqNum);
        userOrderInfo.setTxnDate(DateUtil.getCurrentDate());
        userOrderInfo.setTxnTime(DateUtil.getCurrentTime());
        userOrderInfo.setOrderDesc("银联商户退款");
        userOrderInfo.setOrderCreateTime(DateUtil.getCurrentDateTime("yyyyMMddHHmmss"));
        userOrderInfo.setOrderAmt(posQrCodeConsumeRefundRequest.getTransAmt());
        userOrderInfo.setOrderCcy(oriUserOrderInfo.getOrderCcy());
        /*设置退款订单号为系统流水号*/
        userOrderInfo.setMchntOrderId(sysSeqNum);
        /*设置前端流水号*/
        userOrderInfo.setFrontSeqNum(posQrCodeConsumeRefundRequest.getHeader().getTraceNo());
        userOrderInfo.setUserOrderId(sysSeqNum);
        /*设置订单失效时间,默认五分钟*/
        userOrderInfo.setOrderExpiryTime(DateUtil.getDateByTimeStamp(System.currentTimeMillis() + 300 * 1000, "yyyyMMddHHmmss"));
        /*处理生效时间*/
        userOrderInfo.setOrderStatus(OrderStatusEnum.INIT.getStatus());
        userOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        userOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        userOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        userOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        /*登记商户订单表*/
        BeanUtil.beanCopy(userOrderInfo, mchntOrderInfo);
        /*设置商户订单中其他字段值
        需要查询商户信息表，获取商户相关信息*/
        mchntOrderInfo.setMchntName(oriMchntOrderInfo.getMchntName());
        mchntOrderInfo.setTermNo(posQrCodeConsumeRefundRequest.getTermNo());
        mchntOrderInfo.setMchntSettleAmt("0");
        mchntOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        mchntOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        mchntOrderInfo.setIndustryType(oriMchntOrderInfo.getIndustryType());
        mchntOrderInfo.setAcqInstCode(oriMchntOrderInfo.getAcqInstCode());

        mchntOrderInfo.setOrigSysSeqNum(oriMchntOrderInfo.getSysSeqNum());
        mchntOrderInfo.setOrigTxnDate(oriMchntOrderInfo.getTxnDate());
        mchntOrderInfo.setBizProdCode(oriMchntOrderInfo.getBizProdCode());
        mchntOrderInfo.setMchntNo(posQrCodeConsumeRefundRequest.getMchntNo());
        mchntOrderInfo.setChainMchntNo(oriMchntOrderInfo.getChainMchntNo());
        /*设置收银员id*/
        if (null == oriMchntOrderInfo.getUserId()) {
            mchntOrderInfo.setUserId(null);
        } else {
            mchntOrderInfo.setUserId(oriMchntOrderInfo.getUserId());
        }
        mchntOrderInfo.setRealSettleFlag("N");
        /*设置商户实际应该清算金额*/
        mchntOrderInfo.setRealSettleAmt(posQrCodeConsumeRefundRequest.getTransAmt());
        /*计算商户手续费*/
        if (AmountUtil.compare(posQrCodeConsumeRefundRequest.getTransAmt(), oriMchntOrderInfo.getOrderAmt()) == 0) {
            /*全额退款*/
            /*退款应退手续*/
            mchntOrderInfo.setMchntFee(oriMchntOrderInfo.getMchntFee());
            mchntOrderInfo.setRealMchntFee(oriMchntOrderInfo.getRealMchntFee());
            mchntOrderInfo.setMchntDiscountFee(oriMchntOrderInfo.getMchntDiscountFee());
            mchntOrderInfo.setMchntSettleAmt(oriMchntOrderInfo.getMchntSettleAmt());
            mchntOrderInfo.setCustomerMarketAmt(oriMchntOrderInfo.getCustomerMarketAmt());
        } else {
            /* 部分退款，判断是否为最后一次退款 */
            String totalRefundAmt = AmountUtil.addition(oriMchntOrderInfo.getRefundAmt(), posQrCodeConsumeRefundRequest.getTransAmt());
            if (AmountUtil.compare(totalRefundAmt, oriMchntOrderInfo.getOrderAmt()) == 0) {
                String readyFefundRate = AmountUtil.division(oriMchntOrderInfo.getRefundAmt(), oriMchntOrderInfo.getOrderAmt(), 2);
                String readyCustomerMarketAmt = AmountUtil.multiplication(oriMchntOrderInfo.getCustomerMarketAmt(), readyFefundRate, 2);
                mchntOrderInfo.setCustomerMarketAmt(AmountUtil.subtraction(oriMchntOrderInfo.getCustomerMarketAmt(), readyCustomerMarketAmt));
                mchntOrderInfo.setRealSettleAmt(AmountUtil.subtraction(posQrCodeConsumeRefundRequest.getTransAmt(), mchntOrderInfo.getCustomerMarketAmt()));
            } else {
                String refundRate = AmountUtil.division(posQrCodeConsumeRefundRequest.getTransAmt(), oriMchntOrderInfo.getOrderAmt(), 2);
                String customerMarketAmt = AmountUtil.multiplication(oriMchntOrderInfo.getCustomerMarketAmt(), refundRate, 2);
                mchntOrderInfo.setCustomerMarketAmt(customerMarketAmt);
                mchntOrderInfo.setRealSettleAmt(AmountUtil.subtraction(posQrCodeConsumeRefundRequest.getTransAmt(), customerMarketAmt));
            }
            /*计算退款手续费*/
            boolean calcResult = mchntService.calcMchntRefundFee(mchntOrderInfo, oriMchntOrderInfo);
            if (!calcResult) {
                rglog.error("商户手续费计算失败:商户号{},业务产品代码{}", oriMchntOrderInfo.getMchntNo(), oriMchntOrderInfo.getBizProdCode());
                throw new BizException(RespCodeEnum.CALC_MCHNT_FEE_ERROR.getRespCode(), RespCodeEnum.CALC_MCHNT_FEE_ERROR.getRespDesc());
            }
            rglog.debug("退款应退手续:<{}>", mchntOrderInfo.getMchntFee());
            /*商户实际退款手续费*/
            mchntOrderInfo.setRealMchntFee(mchntOrderInfo.getMchntFee());
            /*商户实际退款金额*/
            mchntOrderInfo.setMchntSettleAmt(AmountUtil.subtraction(posQrCodeConsumeRefundRequest.getTransAmt(),
                    mchntOrderInfo.getRealMchntFee()));
        }

        List<MchntOrderInfo> mchntOrderInfoList = new ArrayList<MchntOrderInfo>();
        mchntOrderInfoList.add(mchntOrderInfo);

        /*登记用户订单表和商户订单表*/
        boolean iReturnCode = orderService.registerOrderInfo(userOrderInfo, mchntOrderInfoList, null);
        if (false == iReturnCode) {
            rglog.error("登记支付订单信息失败,iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespCode(), RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespDesc());
        }
        /*保存用户订单、商户订单、商户账户信息于内部树*/
        xmlTreeUtil.setXmlTreeObjectValue(McpsTreeNodeConstant.USER_ORDER_INFO, userOrderInfo);
        xmlTreeUtil.setXmlTreeObjectValue(McpsTreeNodeConstant.MCHNT_ORDER_INFO, mchntOrderInfo);
    }

    /*更新用户订单表*/
    private void updateFailOrderInfo(String remark, UserOrderInfo userOrderInfo, MchntOrderInfo mchntOrderInfo) throws Exception {
        /*更新用户订单表和商户订单表，状态为失败，并抛出异常
        从内部树中获取userOrderInfo对象的信息；
        设置用户订单的信息和状态,设置订单状态：01（订单关闭） 交易状态:2（交易失败） 业务状态：00（处理成功）*/
        userOrderInfo.setOrderStatus(OrderStatusEnum.CLOSE.getStatus());
        userOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
        userOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
        /*设置失败相应信息*/
        userOrderInfo.setRemark3(remark);
        /*设置商户订单状态和信息，设置商户订单状态，交易状态:01(失败) 业务状态：00（处理完成）*/
        mchntOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
        mchntOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
        /*设置失败信息*/
        mchntOrderInfo.setRemark3(remark);
        //更新用户订单表和商户订单表状态
        updateOrderInfo(userOrderInfo, mchntOrderInfo, null);
    }

    /*
     * 更新用户订单、商户订单
     * */
    private void updateOrderInfo(UserOrderInfo userOrderInfo, MchntOrderInfo mchntOrderInfo, PayOrderInfo payOrderInfo) throws Exception {
        List<MchntOrderInfo> mchntOrderInfoList = new ArrayList<MchntOrderInfo>();
        mchntOrderInfoList.add(mchntOrderInfo);
        OrderService orderService = new OrderServiceImpl();
        boolean iReturnCode = orderService.updateOrderInfo(userOrderInfo, mchntOrderInfoList, payOrderInfo);
        if (false == iReturnCode) {
            rglog.error("更新订单信息失败,iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespCode(), RespCodeEnum.INSERT_ORDER_INFO_ERROR.getRespDesc());
        }
    }
}
